home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
The Regulator 1.4
/
main.c
next >
Wrap
C/C++ Source or Header
|
1993-06-04
|
9KB
|
246 lines
/*------------------------------------------------------------------------------
#
# Apple Developer Technical Support
#
# SmallDaemon
# A small faceless background-only application
#
# main.c - C Source
#
# Copyright © 1991 Apple Computer, Inc.
# All rights reserved.
#
# Versions:
# 1.0 09/91 C.K. Haun <TR>
#
# Components:
# main.c
# AppleEvents.c
#
# This is a _very_ simple sample showing a do-nothing
# System 7.0 faceless background application.
#
# The main things to note are....
# 1) Look at the SIZE resource for the flag settings you'll
# need to let the Finder™ know that you only want to work
# in the background.
# 2) Notice that you really do have your own heap and your own
# event loop. You can do anything a foreground application
# can do, send AppleEvents, PPC stuff, anything else you'd
# like EXCEPT a graphic interface.
# 3) NOTE that no managers are started up. You cannot start up
# Window, Menu, Dialogs, or anything else that
# deals with the graphic front end. Just leave them out.
# You _can_ start up QuickDraw, if you want to use some QuickDraw
# functions (like offscreen ports), but you CANNOT actually
# do any screen drawing.
#
# Of course, a backgrounder can be launched from the Finder™
# with a double-click. However, if you'd like the backgrounder
# to perform some useful service for your main application, driver,
# DA, or whatever, you will want it running all the time.
# The BEST way to insure this is to install the backgrounder in the
# StartUp Items folder in the system folder. This will insure that
# it is always launched, and it will also reduce memory fragmentation
# since it will be installed at startup time. You can search for it
# when you need it with IPCListPorts (see the PPC toolbox documentation).
# Optionally, you can use the LaunchApplication trap to launch it
# when you need it, and kill it when you're done. But this could
# cause some multiFinder heap fragmentation.
#
# And remember, it's a backgrounder, you can't see it. To kill it
# use TaskIt or ProcDoggie.
#
# ---------------------------------------------------------------
# Use this sample as a starting point, and adapt its' routines to
# meet the specific needs of your project.
#
------------------------------------------------------------------------------*/
/* This doesn't do much but wait for a quit event. But, you can expand it */
/* to suit whatever your needs are for a backgrounder. */
/* Be sure to look at the SIZE resource for this app to see how the */
/* flags should be set for a background-only task */
#include <memory.h>
#include <appleevents.h>
#include <events.h>
#include <types.h>
#include <gestaltequ.h>
#include <SegLoad.h>
#include "pb.h"
/* variables */
Boolean gQuit = false;
EventRecord gERecord;
Boolean gHasAppleEvents;
unsigned long gMySleep = 120; /* long time, long time. Change this if */
/* you'd like to do null processing. Just keep in mind that the */
/* user does NOT know that you exist, and if you are eating */
/* up a bunch of time the user will not know why his or her */
/* machine is slowing down. */
/* structs */
/* a little struct to install handlers from. Makes it easier to plug in */
/* new handlers */
struct AEinstalls {
AEEventClass theClass;
AEEventID theEvent;
EventHandlerProcPtr theProc;
};
typedef struct AEinstalls AEinstalls;
/* prototypes for this file */
pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
void DoHighLevel(EventRecord *AERecord);
void InitAEStuff(void);
main()
{
/* We are NOT initializing any managers. We're in the background, with no */
/* face, we can't use windows or dialogs or menus. If you need to talk to the */
/* user you can post a notification, or launch an application to communicate */
/* Passing an AppleEvent in the launchapplication trap could do the */
/* communication for you. */
#ifdef MPW
extern void _DataInit();
UnloadSeg((Ptr)_DataInit);
#endif
InitGraf((Ptr) &qd.thePort);
/* Routine to install Apple event handlers */
InitAEStuff();
InitPrefs(); // opens the prefs resource file, reads in the user's times
InitPortableStuff();
/* no nothing but high level events */
while (gQuit == false) {
WaitNextEvent(highLevelEventMask, &gERecord, gMySleep, 0);
CheckForMains();
switch (gERecord.what) {
case kHighLevelEvent:
DoHighLevel(&gERecord);
break;
}
}
}
/* Here are the AppleEvent handlers for this background-only task. */
/* Since this is a real live application, it can accept and send any */
/* Apple Events you want to send or receive. */
/* In this case, the only ones that make any sense in this app are */
/* 'oapp' and 'quit' */
/* InitAEStuff checks for the availability of the AppleEvent Manager and */
/* installs our event handlers. */
/* if the AEM isn't around, we bail. */
void InitAEStuff(void)
{
static AEinstalls HandlersToInstall[] = {
{
kCoreEventClass, kAEOpenApplication, AEOpenHandler
}, {
kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
}, {
kCoreEventClass, kAEQuitApplication, AEQuitHandler
}, {
kCoreEventClass, kAEPrintDocuments, AEPrintHandler
},
/* The above are the four required AppleEvents. */
};
OSErr aevtErr = noErr;
long aLong = 0;
Boolean gHasAppleEvents = false;
/* Check this machine for AppleEvents. If they are not here (ie not 7.0)
* then we exit */
gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
/* The following series of calls installs all our AppleEvent Handlers.
* These handlers are added to the application event handler list that
* the AppleEvent manager maintains. So, whenever an AppleEvent happens
* and we call AEProcessEvent, the AppleEvent manager will check our
* list of handlers and dispatch to it if there is one.
*/
if (gHasAppleEvents) {
register qq;
for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
HandlersToInstall[qq].theProc, 0, false);
if (aevtErr) {
/* Of course, you can't tell the user why you died directly, since you have no face. */
/* But, you can post a notification from here to let them know. */
ExitToShell(); /* just fail, baby */
}
}
} else {
ExitToShell();
}
}
/* end InitAEStuff */
void DoHighLevel(EventRecord *AERecord)
{
/* I'm not doing any error handling here because there's not a lot */
/* I can do, just pass the errors back. */
AEProcessAppleEvent(AERecord);
}
/* end DoHighLevel */
/* This is the standard Open Application event. */
pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
{
#pragma unused (messagein,reply,refIn)
/* we of course don't do anything here, since we're background only */
/* But this was a normal launch, so return noErr */
return(noErr);
}
/* end AEOpenHandler */
/* Open Doc, opens our documents. */
/* In this case, of course, you are in the background so you should return an error */
/* here since you're not opening a document. */
/* Of course, you _might_ want to open a doc, but you will probably */
/* confuse the user if you do, since they will see no action as the */
/* result of their clicking on a document icon. */
pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
{
#pragma unused (reply, refIn,messagein)
/* we of course don't do anything here, so tell the sender that we */
/* didn't handle the event */
return(errAEEventNotHandled);
}
/* same logic for printing */
pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
{
#pragma unused (reply,refIn,messagein)
/* we of course don't do anything here */
return(errAEEventNotHandled);
}
/* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
/* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
{
#pragma unused (messagein,refIn,reply)
extern Boolean Quit;
/* This does _NOT_ quit, you */
/* should NEVER quit from an AppleEvent handler. Calling */
/* ExitToShell here would blow up the Finder™ */
SetRest();
SetSysSleep(gSysSleep);
SetHDSleep(gHDSleep);
gQuit = true;
return(noErr);
}